from select import*
from socket import*

def main(server_port):
    # 1.创建套接字，绑定操作
    server_socket = socket(AF_INET, SOCK_STREAM)
    server_socket.bind(('', server_port))
    server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)  #地址复用
    server_socket.listen(5) # 限定最大并行连接数量：5
    print("服务器已启动")

    inputs = [server_socket]
    timeout=10#设置超时时间10s，避免客户端无期限阻塞等待

    while True:
        readable, writable, exceptional = select(inputs, [], [],timeout)  #select监听可读事件

        for sock in readable:
            if sock == server_socket: #新的连接请求
                client_connect, addr = server_socket.accept()#连接套接字
                print(f"与客户端{addr}建立连接")
                client_connect.setblocking(False)  #套接字设置为非阻塞模式
                inputs.append(client_connect)  #连接套接字添加到inputs列表
            else: # sock = connection_socket
                try:
                    message = sock.recv(1024)
                    #initialization
                    if message:
                        Type=message[:2].decode()

                        if Type=="01":
                            #agreement
                            N=int(message[2:].decode())
                            Type="02"
                            sock.send(f"{Type}".encode())

                        elif Type=="03":
                            #reverserequest
                            Type="04"
                            length=message[2:5].decode()
                            date=message[5:].decode()
                            # print(date)

                            #reversereply
                            reverse_data=date[::-1]#切片反转字符串
                            sock.send(f"{Type}{length}{reverse_data}".encode())

                        elif message.decode()=="close":
                            print(f"与客户端{sock.getpeername()}断开连接")
                            inputs.remove(sock)
                    else:
                        print(f"客户端{sock.getpeername()}强制断开连接")
                        inputs.remove(sock)
                        sock.close()

                except BlockingIOError:
                    # 客户端强制断开连接
                    print(f"客户端{sock.getpeername()}强制断开连接")
                    inputs.remove(sock)
                    sock.close()

        if not readable:
            print("超时，没有数据接收，客户端关闭")
            for sock in inputs:
                print(f"客户端{sock.getpeername()}超时未活动，正在关闭连接...")
                inputs.remove(sock)
                sock.close()
            server_socket.close()

if __name__ == '__main__':
    server_port = 12345
    main(server_port)